1 /*
2 * Copyright (C) 2011 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 * express or implied. See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15 package com.google.common.primitives;
16
17 import static com.google.common.base.Preconditions.checkArgument;
18 import static com.google.common.base.Preconditions.checkNotNull;
19
20 import com.google.common.annotations.GwtCompatible;
21
22 import java.io.Serializable;
23 import java.math.BigInteger;
24
25 import javax.annotation.CheckReturnValue;
26 import javax.annotation.Nullable;
27
28 /**
29 * A wrapper class for unsigned {@code long} values, supporting arithmetic operations.
30 *
31 * <p>In some cases, when speed is more important than code readability, it may be faster simply to
32 * treat primitive {@code long} values as unsigned, using the methods from {@link UnsignedLongs}.
33 *
34 * <p>See the Guava User Guide article on <a href=
35 * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
36 * unsigned primitive utilities</a>.
37 *
38 * @author Louis Wasserman
39 * @author Colin Evans
40 * @since 11.0
41 */
42 @GwtCompatible(serializable = true)
43 public final class UnsignedLong extends Number implements Comparable<UnsignedLong>, Serializable {
44
45 private static final long UNSIGNED_MASK = 0x7fffffffffffffffL;
46
47 public static final UnsignedLong ZERO = new UnsignedLong(0);
48 public static final UnsignedLong ONE = new UnsignedLong(1);
49 public static final UnsignedLong MAX_VALUE = new UnsignedLong(-1L);
50
51 private final long value;
52
53 private UnsignedLong(long value) {
54 this.value = value;
55 }
56
57 /**
58 * Returns an {@code UnsignedLong} corresponding to a given bit representation.
59 * The argument is interpreted as an unsigned 64-bit value. Specifically, the sign bit
60 * of {@code bits} is interpreted as a normal bit, and all other bits are treated as usual.
61 *
62 * <p>If the argument is nonnegative, the returned result will be equal to {@code bits},
63 * otherwise, the result will be equal to {@code 2^64 + bits}.
64 *
65 * <p>To represent decimal constants less than {@code 2^63}, consider {@link #valueOf(long)}
66 * instead.
67 *
68 * @since 14.0
69 */
70 public static UnsignedLong fromLongBits(long bits) {
71 // TODO(user): consider caching small values, like Long.valueOf
72 return new UnsignedLong(bits);
73 }
74
75 /**
76 * Returns an {@code UnsignedLong} representing the same value as the specified {@code long}.
77 *
78 * @throws IllegalArgumentException if {@code value} is negative
79 * @since 14.0
80 */
81 public static UnsignedLong valueOf(long value) {
82 checkArgument(value >= 0,
83 "value (%s) is outside the range for an unsigned long value", value);
84 return fromLongBits(value);
85 }
86
87 /**
88 * Returns a {@code UnsignedLong} representing the same value as the specified
89 * {@code BigInteger}. This is the inverse operation of {@link #bigIntegerValue()}.
90 *
91 * @throws IllegalArgumentException if {@code value} is negative or {@code value >= 2^64}
92 */
93 public static UnsignedLong valueOf(BigInteger value) {
94 checkNotNull(value);
95 checkArgument(value.signum() >= 0 && value.bitLength() <= Long.SIZE,
96 "value (%s) is outside the range for an unsigned long value", value);
97 return fromLongBits(value.longValue());
98 }
99
100 /**
101 * Returns an {@code UnsignedLong} holding the value of the specified {@code String}, parsed as
102 * an unsigned {@code long} value.
103 *
104 * @throws NumberFormatException if the string does not contain a parsable unsigned {@code long}
105 * value
106 */
107 public static UnsignedLong valueOf(String string) {
108 return valueOf(string, 10);
109 }
110
111 /**
112 * Returns an {@code UnsignedLong} holding the value of the specified {@code String}, parsed as
113 * an unsigned {@code long} value in the specified radix.
114 *
115 * @throws NumberFormatException if the string does not contain a parsable unsigned {@code long}
116 * value, or {@code radix} is not between {@link Character#MIN_RADIX} and
117 * {@link Character#MAX_RADIX}
118 */
119 public static UnsignedLong valueOf(String string, int radix) {
120 return fromLongBits(UnsignedLongs.parseUnsignedLong(string, radix));
121 }
122
123 /**
124 * Returns the result of adding this and {@code val}. If the result would have more than 64 bits,
125 * returns the low 64 bits of the result.
126 *
127 * @since 14.0
128 */
129 public UnsignedLong plus(UnsignedLong val) {
130 return fromLongBits(this.value + checkNotNull(val).value);
131 }
132
133 /**
134 * Returns the result of subtracting this and {@code val}. If the result would have more than 64
135 * bits, returns the low 64 bits of the result.
136 *
137 * @since 14.0
138 */
139 public UnsignedLong minus(UnsignedLong val) {
140 return fromLongBits(this.value - checkNotNull(val).value);
141 }
142
143 /**
144 * Returns the result of multiplying this and {@code val}. If the result would have more than 64
145 * bits, returns the low 64 bits of the result.
146 *
147 * @since 14.0
148 */
149 @CheckReturnValue
150 public UnsignedLong times(UnsignedLong val) {
151 return fromLongBits(value * checkNotNull(val).value);
152 }
153
154 /**
155 * Returns the result of dividing this by {@code val}.
156 *
157 * @since 14.0
158 */
159 @CheckReturnValue
160 public UnsignedLong dividedBy(UnsignedLong val) {
161 return fromLongBits(UnsignedLongs.divide(value, checkNotNull(val).value));
162 }
163
164 /**
165 * Returns this modulo {@code val}.
166 *
167 * @since 14.0
168 */
169 @CheckReturnValue
170 public UnsignedLong mod(UnsignedLong val) {
171 return fromLongBits(UnsignedLongs.remainder(value, checkNotNull(val).value));
172 }
173
174 /**
175 * Returns the value of this {@code UnsignedLong} as an {@code int}.
176 */
177 @Override
178 public int intValue() {
179 return (int) value;
180 }
181
182 /**
183 * Returns the value of this {@code UnsignedLong} as a {@code long}. This is an inverse operation
184 * to {@link #fromLongBits}.
185 *
186 * <p>Note that if this {@code UnsignedLong} holds a value {@code >= 2^63}, the returned value
187 * will be equal to {@code this - 2^64}.
188 */
189 @Override
190 public long longValue() {
191 return value;
192 }
193
194 /**
195 * Returns the value of this {@code UnsignedLong} as a {@code float}, analogous to a widening
196 * primitive conversion from {@code long} to {@code float}, and correctly rounded.
197 */
198 @Override
199 public float floatValue() {
200 @SuppressWarnings("cast")
201 float fValue = (float) (value & UNSIGNED_MASK);
202 if (value < 0) {
203 fValue += 0x1.0p63f;
204 }
205 return fValue;
206 }
207
208 /**
209 * Returns the value of this {@code UnsignedLong} as a {@code double}, analogous to a widening
210 * primitive conversion from {@code long} to {@code double}, and correctly rounded.
211 */
212 @Override
213 public double doubleValue() {
214 @SuppressWarnings("cast")
215 double dValue = (double) (value & UNSIGNED_MASK);
216 if (value < 0) {
217 dValue += 0x1.0p63;
218 }
219 return dValue;
220 }
221
222 /**
223 * Returns the value of this {@code UnsignedLong} as a {@link BigInteger}.
224 */
225 public BigInteger bigIntegerValue() {
226 BigInteger bigInt = BigInteger.valueOf(value & UNSIGNED_MASK);
227 if (value < 0) {
228 bigInt = bigInt.setBit(Long.SIZE - 1);
229 }
230 return bigInt;
231 }
232
233 @Override
234 public int compareTo(UnsignedLong o) {
235 checkNotNull(o);
236 return UnsignedLongs.compare(value, o.value);
237 }
238
239 @Override
240 public int hashCode() {
241 return Longs.hashCode(value);
242 }
243
244 @Override
245 public boolean equals(@Nullable Object obj) {
246 if (obj instanceof UnsignedLong) {
247 UnsignedLong other = (UnsignedLong) obj;
248 return value == other.value;
249 }
250 return false;
251 }
252
253 /**
254 * Returns a string representation of the {@code UnsignedLong} value, in base 10.
255 */
256 @Override
257 public String toString() {
258 return UnsignedLongs.toString(value);
259 }
260
261 /**
262 * Returns a string representation of the {@code UnsignedLong} value, in base {@code radix}. If
263 * {@code radix < Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}, the radix
264 * {@code 10} is used.
265 */
266 public String toString(int radix) {
267 return UnsignedLongs.toString(value, radix);
268 }
269 }